<script lang="jsx">
import { buttonKeys, formatData, mergeVModel, type } from './utils'
import request from '@/utils/request'

export default {
  name: 'CrudTableFormDialog',
  props: {
    config: Object
  },
  data() {
    return {
      visible: false,
      isSaving: false,
      formDisabled: false,
      form: {},
      editRowIndex: null, // 所修改的行索引
    }
  },
  inject: ['view', 'add', 'edit', 'debug', 'size'],
  created() {
    this.cacheDialogFormFields = Object.create(null)
    const { inFormatter, outFormatter } = this.config || {}
    if (inFormatter) {
      this.inFormatter = inFormatter
    }
    if (outFormatter) {
      this.outFormatter = outFormatter
    }
  },
  beforeDestory() {
    this.cacheDialogFormFields = null
    this.inFormatter = null
    this.outFormatter = null
  },
  methods: {
    open(props, formDisabled = false) {
      this.formDisabled = formDisabled
      if (props !== undefined) {
        this.editRowIndex = props.$index
        this.form = formatData(props.row, this.inFormatter)
      }
      // console.log(this.form);
      this.visible = true
      this.$emit('innerDialogChange', true)
    },
    onDialogClosed() {
      this.editRowIndex = null
      this.form = { ...this.cacheDialogFormFields }
      this.$refs.form.resetFields()
      this.$emit('innerDialogChange', false)
    },
    onDialogSave() {
      this.$refs.form.validate(async v => {
        if (v) {
          this.isSaving = true
          const actionType = this.editRowIndex == null ? buttonKeys.ADD : buttonKeys.EDIT
          const fmtData = formatData(this.form, this.outFormatter)
          if (this.debug) console.log('fmtData', fmtData)
          const reqBody = {
            method: actionType === buttonKeys.ADD ? 'post' : 'put'
          }
          const config = this[actionType]
          if (type(config) === 'string') {
            // reqBody.url = actionType === buttonKeys.ADD ? config : (config + '?id=' + fmtData.id + '')
            reqBody.url = config
          }
          if (type(config) === 'object') {
            const { url, data, ...rest } = config
            // reqBody.url = actionType === buttonKeys.ADD ? url : (config + '?id=' + fmtData.id + '')
            reqBody.url = url
            if (data) Object.assign(fmtData, data)
            Object.assign(reqBody, rest)
          }
          reqBody.data = fmtData
          if (this.debug && process.env.NODE_ENV === 'development') {
            // console.log(this.$message.info('CrudTable组件开启了debug模式，因此数据不会真实发送'))
            console.log(reqBody)
            this.isSaving = false
            return
          }
          try {
            const resp = await request(reqBody)
            const msg = resp.msg === 'success' ? '操作成功' : resp.msg
            this.$message.success(msg)
            this.visible = false
            this.$emit('save-success', {
              type: actionType,
              resData: resp.data,
              formData: fmtData
            })
          } finally {
            this.isSaving = false
          }
        }
      })
    },
    setFormFidld(key, value, cache = false) {
      this.$set(this.form, key, value)
      if (cache) this.cacheDialogFormFields[key] = value
    }
  },
  render() {
    const size = this.size
    const config = this.config
    const { dialogForm: dialogFormSlot } = this.$scopedSlots
    const dialogFormNodes = dialogFormSlot && mergeVModel(dialogFormSlot({ form: this.form }), this.form)
    if(!config) return null
    return (
      <ElDialog
        class="dialog-container"
        title={ (this.formDisabled ? '' : (this.editRowIndex !== null ? '编辑' : '新增')) + (config?.topic || '') }
        close-on-click-modal={ this.formDisabled }
        close-on-press-escape={ this.formDisabled }
        visible={ this.visible }
        append-to-body
        top='10vh'
        width= '50%'
        on-closed={ this.onDialogClosed }
        {
          ...{
            props: config?.dialogProps || {},
            on: {
              'update:visible': val => this.visible = val
            }
          }
        }
      >
        <ElForm
          ref='form'
          label-position='left'
          size={size}
          label-width='110px'
          disabled={this.formDisabled}
          {
            ...{
              props: Object.assign(config?.formProps || {}, { model: this.form })
            }
          }
        >
          { dialogFormNodes }
        </ElForm>
        <div slot='footer' v-show={!this.formDisabled}>
          <ElButton size={size} type='default' on-click={ () => this.visible = false }>取消</ElButton>
          <ElButton size={size} loading={ this.isSaving } type='primary' on-click={ () => this.onDialogSave() } >保存</ElButton>
        </div>
      </ElDialog>
    )
  }
}
</script>

<style lang="scss" scoped>
.dialog-container ::v-deep .el-dialog__body {
  padding-top: 0px;
  height: 600px;
  overflow: hidden;
  overflow-y: auto;
  @include scrollBar(#d3dce6,6px)
  }
</style>
